package br.ufc.es.pds.mudproject.main;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;

import br.ufc.es.pds.mudproject.annotations.ComandoAnnotation;
import br.ufc.es.pds.mudproject.comandos.*;
import br.ufc.es.pds.mudproject.core.Comando;
import br.ufc.es.pds.mudproject.core.Jogador;
import br.ufc.es.pds.mudproject.objects.CartaoMatricula;

public class Interpretador {

	private Invoker invoker;
	private boolean run;
	private Scanner entrada;
	private Jogador jogador;
	private Setup setup;
	private HashMap<String, Class> todosOsComandos;
	
	public Interpretador(){
		invoker = new Invoker();
		entrada = new Scanner(System.in);
		setup = new Setup();
		invoker.start();
		todosOsComandos = new HashMap<>();
		this.carregarComandos(todosOsComandos);
		this.run();
	}
	
	public void run(){
		
		this.telaInicial();
		
		System.out.println("Seja Bem Vindo ao MUD Project");
		this.carregarInformacoesDoUsuario();
		
		while( true ){
			System.out.println("O que deseja fazer?");
			this.interpretar( entrada.nextLine() );
			
		}
		
	}
	
	private void interpretar( String entrada ){
		String[] entradas = entrada.split(" ");	
		String comandoPrincipal = new String(entradas[0]);
		ArrayList<String> parametros = new ArrayList<String>();
		
		/* Converte o Vetor para uma ArrayList */
		for (int i = 1; i < entradas.length; i++) {
			parametros.add(entradas[i]);
		}
		
		/* Procura o comando no hashmap de comandos existentes
		 * e lança uma nova intancia para execução */
		for (String comandoAtual : todosOsComandos.keySet() ) {
			Comando comandoASerExcutado;
			if ( comandoPrincipal.equalsIgnoreCase(comandoAtual) ) {
				try {
					comandoASerExcutado = (Comando) todosOsComandos.get(comandoAtual).getDeclaredConstructor(new Class[]{Jogador.class,ArrayList.class}).newInstance(new Object[]{jogador,parametros});
					invoker.adicionarComando(comandoASerExcutado);
				} catch (InstantiationException | IllegalAccessException
						| IllegalArgumentException | InvocationTargetException
						| NoSuchMethodException | SecurityException e) {
					e.printStackTrace();
				}
			}	
		}
	}
	
	private void carregarInformacoesDoUsuario(){
		String nome = "";
		while ( nome.isEmpty()) {
			System.out.println("Digite o nome do Usuario: ");
			nome = entrada.nextLine();
		}
		String descricao = "";
		while( descricao.isEmpty() ) {
			System.out.println("Digite uma descrição: ");
			descricao = entrada.nextLine();
		}
		
		jogador = new Jogador(nome, descricao);
		
		System.out.println("Olá " + jogador.pegarNome() + ", " + jogador.pegarDescricao() +" !");
		jogador.setAmbiente(setup.pegarMapaInicial());		
		jogador.adicionarObjeto(new CartaoMatricula());

		System.out.println("Digite HELP, se precisar de ajuda.");
		
		jogador.pegarAmbiente().exibirTudoDaSala();
	}
		
	public void telaInicial(){
		System.out.println("   _____   ____ ___________   ");
		System.out.println("  /     \\ |    |   \\______ \\  ");
		System.out.println(" /  \\ /  \\|    |   /|    |  \\ ");
		System.out.println("/    Y    \\    |  / |    `   \\");
		System.out.println("\\____|__  /______/ /_______  /");
		System.out.println("        \\/                 \\/ ");
		System.out.println("__________                   __               __   ");
		System.out.println("\\______   \\_______  ____    |__| ____   _____/  |_ ");
		System.out.println(" |     ___/\\_  __ \\/  _ \\   |  |/ __ \\_/ ___\\   __\\");
		System.out.println(" |    |     |  | \\(  <_> )  |  \\  ___/\\  \\___|  |  ");
		System.out.println(" |____|     |__|   \\____/\\__|  |\\___  >\\___  >__|  ");
		System.out.println("                        \\______|    \\/     \\/      ");
		System.out.println(" ");
	}

	private void carregarComandos( HashMap<String, Class> comandos) {
		
		comandos.put(ComandoAcionar.class.getAnnotation(ComandoAnnotation.class).comando(), ComandoAcionar.class);
		comandos.put(ComandoAndar.class.getAnnotation(ComandoAnnotation.class).comando(), 	ComandoAndar.class);
		comandos.put(ComandoDar.class.getAnnotation(ComandoAnnotation.class).comando(), 	ComandoDar.class);
		comandos.put(ComandoFalar.class.getAnnotation(ComandoAnnotation.class).comando(), 	ComandoFalar.class);
		comandos.put(ComandoHelp.class.getAnnotation(ComandoAnnotation.class).comando(), 	ComandoHelp.class);
		comandos.put(ComandoPegar.class.getAnnotation(ComandoAnnotation.class).comando(), 	ComandoPegar.class);
		comandos.put(ComandoStatus.class.getAnnotation(ComandoAnnotation.class).comando(), 	ComandoStatus.class);
		comandos.put(ComandoUsar.class.getAnnotation(ComandoAnnotation.class).comando(), 	ComandoUsar.class);
		comandos.put(ComandoSair.class.getAnnotation(ComandoAnnotation.class).comando(), 	ComandoSair.class);

	}
	
}
